using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class FormController : MonoBehaviour {

    public static FormController Current { get; set; }

    [SerializeField]
    GameObject _defaultForm;

    [SerializeField]
    Transform _formParent;

    public StringEvent OnChangeForm;

    string _currentForm;

    List<string> enabledForms = new List<string>();
    Dictionary<string, GameObject> formObjects = new Dictionary<string, GameObject>();

    #region Properties
    public string CurrentForm {
        get { return _currentForm; }
        set { _currentForm = value; }
    }

    public int FormCount {
        get { return enabledForms.Count; }
    }
    #endregion

    void OnEnable() {
        Current = this;
    }

    void Awake() {
        CurrentForm = "Default Form";

        enabledForms.Add(CurrentForm);
        formObjects[CurrentForm] = _defaultForm;
        _defaultForm.transform.parent = null;
    }

    void Start() {
        OnChangeForm.AddListener(FormUIManager.Current.Select);
    }

    void LateUpdate() {
        _defaultForm.transform.position = transform.position;
    }

    public void ActivateForm(string form) {
        if(enabledForms.Contains(form)) {
            foreach(GameObject gameObject in formObjects.Values) {
                FormAnimator formAnimator = gameObject.GetComponent<FormAnimator>();

                if(formAnimator) formAnimator.OnBeforeDisable();

                gameObject.SetActive(false);
            }

            formObjects[form].SetActive(true);

            CurrentForm = form;

            if(OnChangeForm != null) OnChangeForm.Invoke(form);
        }
    }
    public void ActivateForm(float direction) {
        ActivateForm((int)direction);
    }
    public void ActivateForm(int direction) {
        int currentIndex = GetFormIndex(CurrentForm);
        int nextIndex = currentIndex;

        if(FormCount == 0) return;

        nextIndex = (nextIndex + direction) % FormCount;

        if(nextIndex < 0) nextIndex += FormCount;
        if(currentIndex != nextIndex) ActivateFormByIndex(nextIndex);
    }
    public void ActivateFormByIndex(int index) {
        ActivateForm(enabledForms[index]);
    }

    public void DisableForm(string form) {
        if(enabledForms.Remove(form)) {
            Destroy(formObjects[form]);
            formObjects.Remove(form);
        }
    }

    public void EnableForm(string form) {
        if(!enabledForms.Contains(form)) {
            enabledForms.Add(form);

            formObjects[form] = FormManager.Current.SpawnForm(form);
            formObjects[form].transform.SetParent(_formParent, false);
            formObjects[form].transform.localPosition = Vector3.zero;
            formObjects[form].BroadcastMessage("ConnectedFormController", this, SendMessageOptions.DontRequireReceiver);
            formObjects[form].gameObject.SetActive(false);

            FormUIManager.Current.AddIcon(form, this);
        }
    }

    public int GetFormIndex(string form) {
        return FormCount > 0 ? enabledForms.IndexOf(form) : -1;
    }

    public string GetFormName(int index) {
        return enabledForms[index];
    }
}